
#include <stdio.h>
#include <stdlib.h>
#include <jconfig.h>
#include <jerror.h>
#include <jmorecfg.h>
#include <jpeglib.h>

#include "lcd.h"

/*
	JPEG_Display: 播放一张jpeg格式的图片 
	@jpeg_pathname: 图片的路径名
	@x0, y0: 图片左上角的坐标
	返回值: 
		无 
*/
void JPEG_Display(const char * jpeg_pathname, int x0, int y0)
{

//1. 分配并初始化一个jpeg解压对象
	
	//struct jpeg_decompress_struct 这个结构体在libjpeg这个库中，
	//是用来保存解压一个jpeg文件所需要的信息的。

	//struct jpeg_error_mgr 这个结构体在libjpeg这个库中
	//是用来保存解压或压缩过程的一些出错信息的。
	
	struct jpeg_decompress_struct dinfo; //声明一个解压的对象
	struct jpeg_error_mgr jerr; //声明一个出错信息的对象

	jpeg_create_decompress(&dinfo); //初始化dinfo这个解压对象
	dinfo.err = jpeg_std_error(&jerr); //初始化这个出错对象
	

//2. 指定要解压缩的图像文件
	//2.1 用标准IO去打开这个文件	 <------
	FILE *infile;
	infile = fopen(jpeg_pathname, "r");
	if (infile == NULL)
	{
		perror("fopen jpeg error");
		return ;
	}
	
	jpeg_stdio_src(&dinfo, infile); //指定要解压的图像文件为解压对象
			
				
//3.调用jpeg_read_header()获取图像信息
	jpeg_read_header(&dinfo, TRUE);
		
	
	
//4.	用于设置jpeg解压对象dinfo的一些参数。可采用默认参数
		//略


//5. 调用jpeg_start_decompress()启动解压过程
	jpeg_start_decompress(&dinfo);
		
	/*调用jpeg_start_decompress函数之后，JPEG解压对象dinfo中
	下面这几个字段(成员变量)将会比较有用：
		dinfo.output_width: 	图像输出宽度，一行占多少个像素点
		dinfo.output_height:	图像输出高度，占多少行
		dinfo.output_components:  每个像素点的分量数，每个像素点占多少个字节
								3： R G B
								4：A R G B
				width * height * components

				
		在调用jpeg_start_decompress之后，往往需要为解压后的扫描线上的
		所有像素点分配存储空间： 
			存一行(一行像素点所占字节数)： 
				dinfo.output_width * dinfo.output_components*/

//6. 读取一行或者多行扫描线上数据并处理，通常的代码是这样子的:
	//大端模式存储
		unsigned char *buffer = malloc(dinfo.output_width * dinfo.output_components);
		int color;
		int i, j;
		unsigned char a, r, g ,b;
		
		//dinfo.output_scanline , 表示的意思是，已经扫描了多少行
		while (dinfo.output_scanline < dinfo.output_height)
		{
			j = dinfo.output_scanline; //记录扫描多少行
			
			jpeg_read_scanlines(&dinfo,  //解压对象
								&buffer,//保存解压后数据的二级指针, 
								1 //读取多少行数据来解压
								);	
			
			//解析一行的数据，并且画图
			unsigned char * p = buffer;
			for(i = 0; i < dinfo.output_width; i++)
			{
				if(dinfo.output_components == 4)
				{
					a = *p; p++;
				}
				else 
				{
					a = 0;
				}
				r = *p; p++;
				g = *p; p++;
				b = *p; p++;
				color = a << 24 | r << 16 | g << 8 | b ;
				LCD_Draw_Point(x0 + i , y0 + j,  color);
			}
			
		}

	
//7. 调用jpeg_finish_decompress()完成解压过程
		jpeg_finish_decompress(&dinfo);

//8. 调用jpeg_destroy_decompress释放jpeg解压对象dinfo
		jpeg_destroy_decompress(&dinfo);

		fclose(infile);
		free(buffer);
}




